package top.lingkang.finalsql.dialect;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import top.lingkang.finalsql.sql.ExSqlEntity;

/**
 * @author lingkang
 * Created by 2022/4/11
 * 方言接口，使用方言处理以适应不同数据库ORM操作
 * 接口默认使用MySQL协议的方言处理
 */
public interface SqlDialect {
    default String one(String sql) {
        return "select " + sql + " limit 1";
    }

    default String count(String sql) {
        return "select count(*) " + sql;
    }

    default String getTableName(String name) {
        return name;
    }

    String nextval(String column);

    /**
     * 分页获取行
     *
     * @param sql   类似添加mysql中的 limit
     * @param start 类似添加mysql中的 limit star,999
     * @param row   类似添加mysql中的 limit 0,row
     * @return
     */
    default String rowSql(String sql, int start, int row) {
        return sql + " limit " + start + "," + row;
    }

    /**
     * 用于分页统计
     */
    default ExSqlEntity total(ExSqlEntity sqlEntity) {
        try {
            // 分词器
            Statement parse = CCJSqlParserUtil.parse(sqlEntity.getSql());
            if (!(parse instanceof Select)) {
                throw new RuntimeException("分词异常, 分页只能用于查询sql，当前sql：" + sqlEntity.getSql());
            }
            String sql = "select count(*) as count from ";
            Select select = (Select) parse;
            PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
            FromItem fromItem = plainSelect.getFromItem();
            sql += fromItem.toString();
            if (plainSelect.getJoins() != null)
                for (Join join : plainSelect.getJoins())
                    sql = sql + " " + join.toString();
            if (plainSelect.getWhere() != null)
                sql += " where " + plainSelect.getWhere().toString();
            return new ExSqlEntity(sql, sqlEntity.getParam());
        } catch (JSQLParserException e) {
            throw new RuntimeException("分词异常：", e);
        }
    }
}
